﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.IO;
using System.Globalization;
using System.Diagnostics;
using debugger;

namespace WindowsFormsApplication1
{

    public sealed partial class Form1 : Base
    {
        public Form1()
        {
            InitializeComponent();

            this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
            this.comboBox1.Click += comboBox1_Click;
            this.textBox1.KeyDown += textBox1_KeyDown;
        }
        void comboBox1_Click(object sender, System.EventArgs e)
        {
            String[] list = SerialPort.GetPortNames();
            this.comboBox1.Items.Clear();
            foreach (String s in list)
            {
                this.comboBox1.Items.Add(s);
            }
            this.comboBox2.SelectedIndex = 0;
        }

        void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (port != null && port.IsOpen)
            {
                port.Close();
            }
        }
        string portName;
        private void Form1_Load(object sender, EventArgs e)
        {
            this.comboBox3.SelectedIndex = 0;
            this.comboBox2.SelectedIndex = 2;
        }
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            portName = (string)this.comboBox1.SelectedItem;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            connect(portName, int.Parse(comboBox3.Text));
        }

        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (fifo.Count > 0)
            {
                while (fifo.Count > 0)
                {
                    char c = fifo.Dequeue();
                    sb1.Append(c);
                    sb2.Append(" " + getHex2((byte)c));
                }
                textBox4.Text = sb1.ToString().Replace('\0', ' ');
                textBox3.Text = sb2.ToString().Replace('\0', ' ');
                this.textBox4.Select(this.textBox4.TextLength, 0);
                textBox4.ScrollToCaret();
            }
        }

        string lastline = "";
        void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                foreach (var item in textBox1.Text)
                {
                    port.Write(new byte[] { (byte)item }, 0, 1);
                }

                if (this.comboBox2.Text == "\\0")
                {
                    port.Write(new byte[] { (byte)0 }, 0, 1);
                }
                if (this.comboBox2.Text == "\\n")
                {
                    port.Write(new byte[] { (byte)'\n' }, 0, 1);
                }
                if (this.comboBox2.Text == "\\r\\n")
                {
                    port.Write(new byte[] { (byte)'\r' }, 0, 1);
                    port.Write(new byte[] { (byte)'\n' }, 0, 1);
                }
                if (this.comboBox2.Text == "\\n\\0")
                {
                    port.Write(new byte[] { (byte)'\n' }, 0, 1);
                    port.Write(new byte[] { (byte)0 }, 0, 1);
                }
                if (this.comboBox2.Text == "\\r\\n\\0")
                {
                    port.Write(new byte[] { (byte)'\r' }, 0, 1);
                    port.Write(new byte[] { (byte)'\n' }, 0, 1);
                    port.Write(new byte[] { (byte)0 }, 0, 1);
                }
                lastline = textBox1.Text;
                textBox1.Text = "";
            }
            else if (e.KeyCode == Keys.Up)
            {
                textBox1.Text = lastline;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            sb1 = new StringBuilder();
            sb2 = new StringBuilder();
            textBox4.Text = sb1.ToString().Replace('\0', ' ');
            textBox3.Text = sb2.ToString().Replace('\0', ' ');
        }

        void upload(string name)
        {
            FileStream fs = new FileStream("..\\mine.new\\" + name, FileMode.Open, FileAccess.Read);
            int len = (int)fs.Length;

            foreach (var item in "upload\n")
            {
                port.Write(new byte[] { (byte)item }, 0, 1);
            }
            Thread.Sleep(1000);
            Application.DoEvents();
            foreach (var item in name + "\n")
            {
                port.Write(new byte[] { (byte)item }, 0, 1);
            }
            Thread.Sleep(1000);
            Application.DoEvents();
            foreach (var item in len + "\n")
            {
                port.Write(new byte[] { (byte)item }, 0, 1);
            }
            Thread.Sleep(1000);
            Application.DoEvents();
            timer1_Tick(null, null);
            this.timer1.Enabled = false;

            for (int i = 0; i < len; i++)
            {
                int val = fs.ReadByte();
                port.Write(new byte[] { (byte)val }, 0, 1);
                char data;
                while (true)
                {
                    if (fifo.Count > 0)
                    {
                        data = fifo.Dequeue();
                        break;
                    }
                }
                if (data != val)
                {
                    throw new Exception();
                }
                this.Text = "" + i;
            }
            this.timer1.Enabled = true;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //upload("mbg.img");
            //MessageBox.Show("ok");
            port.Write(new byte[] { 0, 0 }, 0, 2);

            port.Write(new byte[] { (byte)Convert.ToInt32(textBox1.Text, 16), (byte)1 }, 0, 2);
        }

        private void cmd(uint cmd, uint data)
        {
            port.Write(new byte[] { (byte)cmd, (byte)data }, 0, 2);
        }

        private void write(uint addr, uint data)
        {

            cmd(0x20, (addr >> 0) & 0xFF);
            cmd(0x21, (addr >> 8) & 0xFF);
            cmd(0x22, (addr >> 16) & 0xFF);
            cmd(0x23, (addr >> 24) & 0xFF);

            cmd(0x24, (data >> 0) & 0xFF);
            cmd(0x25, (data >> 8) & 0xFF);
            cmd(0x26, (data >> 16) & 0xFF);
            cmd(0x27, (data >> 24) & 0xFF);

            noPeekData = true;
            cmd(0x51, 0);
            int ret;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (port.BytesToRead == 0)
            {
                if (sw.ElapsedMilliseconds > 100)
                {
                    throw new Exception("timeout");
                }
            }
            ret = port.ReadByte();
            if (ret != 0x34)
            {
                throw new Exception("err");
            }
            noPeekData = false;
        }

        private uint read(uint addr)
        {

            cmd(0x20, (addr >> 0) & 0xFF);
            cmd(0x21, (addr >> 8) & 0xFF);
            cmd(0x22, (addr >> 16) & 0xFF);
            cmd(0x23, (addr >> 24) & 0xFF);

            noPeekData = true;
            cmd(0x50, 0);
            uint ret;
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (port.BytesToRead == 0)
            {
                if (sw.ElapsedMilliseconds > 100)
                {
                    throw new Exception("timeout");
                }
            }
            ret = (uint)port.ReadByte();
            if (ret != 0x33)
            {
                throw new Exception("err");
            }

            cmd(0x10, 0);
            cmd(0x11, 0);
            cmd(0x12, 0);
            cmd(0x13, 0);

            while (port.BytesToRead == 0)
            {
                if (sw.ElapsedMilliseconds > 100)
                {
                    throw new Exception("timeout");
                }
            }
            ret = 0;
            ret |= (uint)port.ReadByte() << 0;
            ret |= (uint)port.ReadByte() << 8;
            ret |= (uint)port.ReadByte() << 16;
            ret |= (uint)port.ReadByte() << 24;

            noPeekData = false;
            return ret;
        }
        private void button4_Click(object sender, EventArgs e)
        {
            write(Convert.ToUInt32(textBox2.Text, 16), Convert.ToUInt32(textBox1.Text,16));
        }

        private void button5_Click(object sender, EventArgs e)
        {
            uint val = read(Convert.ToUInt32(textBox2.Text, 16));
           textBox4.Text = Util.getHex8(val);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            int count = 1024;
            HashSet<uint> addrh = new HashSet<uint>();
            uint[] addr = new uint[count];
            uint[] data = new uint[count];
            Random r = new Random();
            for (int i = 0; i < count; i++)
            {
                while (true)
                {
                    addr[i] = (uint)(r.Next(64 * 1024 * 1024) * 4 + 0x10000000);
                    if (!addrh.Contains(addr[i]))
                    {
                        break;
                    }
                }
                addrh.Add(addr[i]);
                data[i] = (uint)r.Next(int.MinValue, int.MaxValue);
                if ((i & 1023) == 0)
                {
                    this.Text = "a"+i.ToString();
                }
            }
            for (int i = 0; i < count; i++)
            {
                try
                {
                    write(addr[i], data[i]);
                }
                catch
                {

                }
                if ((i & 15) == 0)
                {
                    this.Text = "b" + i.ToString();
                }
            }
            int err = 0;
            for (int i = 0; i < count; i++)
            {
                uint val;
                try
                {
                    val = read(addr[i]);
                }
                catch
                {
                    val = 0;
                }
                if (val != data[i])
                {
                    err++;
                }
                if ((i & 15) == 0)
                {
                    this.Text = "c" + i.ToString();
                }
            }

            this.textBox4.Text = err.ToString();
        }


    }
}
